home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1995-08-07 | 10.3 KB | 283 lines | [TEXT/.Ob4] |
- Syntax10.Scn.Fnt
- StampElems
- Alloc
- 7 Aug 95
- InfoElems
- Alloc
- Syntax10.Scn.Fnt
- StampElems
- Alloc
- 7 Aug 95
- "Title": Run time debugger
- "Author": mah
- "Abstract": Control flow & Breakpoints
- "Keywords":
- "Version":
- "From": 25.10.94 16:53:38
- "Until":
- "Changes":
- ParcElems
- Alloc
- Syntax10i.Scn.Fnt
- Syntax10b.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- Syntax10b.Scn.Fnt
- Syntax10i.Scn.Fnt
- next-: ModuleInfo;
- name-: ARRAY 32 OF CHAR;
- mod: Modules.Module; (* current mod-descriptor when steps written *)
- steps: POINTER TO ARRAY OF LONGINT; (* backup of overwritten instructions *)
- mode: INTEGER; (* NormalMode, StepMode & BreakpointMode *)
- END;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- VAR mod: ModuleInfo; m: Modules.Module; stats: RTDC.Stat; adr, i: LONGINT;
- BEGIN
- mod := modules;
- WHILE mod # NIL DO
- m := SYS.VAL (Modules.Module, mod.mod);
- IF (m.PC <= pc) & (pc < m.PC+m.codesize*4) THEN (* module found *)
- RTDC.Statements (mod.name, stats);
- adr := m.PC;
- FOR i := 0 TO LEN (stats.pc^)-1 DO
- adr := adr + 4*stats.pc[i];
- IF adr = pc THEN RETURN mod.steps[i] END
- END;
- RETURN RTDT.inop
- END;
- mod := mod.next
- END;
- RETURN RTDT.itw
- END InstrAtPC;
- Syntax10.Scn.Fnt
- VAR stats: RTDC.Stat; i, adr: LONGINT; m: Modules.Module;
- BEGIN
- m := Modules.ThisMod (mod.name);
- RTDC.Statements (mod.name, stats);
- IF stats.pc # NIL THEN
- NEW (mod.steps, LEN (stats.pc^));
- adr := m.PC;
- FOR i := 0 TO LEN (stats.pc^)-1 DO
- adr := adr + 4*stats.pc[i];
- SYS.GET (adr, mod.steps[i])
- END
- END GetBackupInstrs;
- Syntax10.Scn.Fnt
- VAR stats: RTDC.Stat; idx, adr, i: LONGINT; m: Modules.Module;
- BEGIN
- IF mod.mode = NormalMode THEN RETURN END;
- m := Modules.ThisMod (mod.name);
- IF mod.mod = m THEN
- RTDC.Statements (mod.name, stats); idx := LEN (stats.pc^);
- IF stats.pc # NIL THEN
- adr := m.PC; FOR i := 0 TO idx-1 DO adr := adr + 4*stats.pc[i] END;
- WHILE idx > 0 DO
- DEC (idx); SYS.PUT (adr, mod.steps[idx]);
- adr := adr - 4*stats.pc[idx]
- END;
- mod.mode := NormalMode
- ELSE
- Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
- Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
- END
- ELSE
- mod.steps := NIL
- END RestoreModule;
- Syntax10.Scn.Fnt
- VAR stats: RTDC.Stat; i, adr: LONGINT; m, d1: Modules.Module; d2, d3, startPC, endPC: LONGINT;
- BEGIN
- m := Modules.ThisMod (mod.name);
- IF m # mod.mod THEN mod.mode := NormalMode; mod.steps := NIL; mod.mod := m END;
- IF (mod.mode = StepOverMode) OR (mod.mode = StepMode) THEN RestoreModule (mod) END;
- IF mod.mode = EntryMode THEN RETURN END;
- IF mod.steps = NIL THEN GetBackupInstrs (mod) END;
- IF mod.steps # NIL THEN
- RTDC.Statements (mod.name, stats);
- adr := m.PC; endPC := 0;
- FOR i := 0 TO LEN (stats.pc^)-1 DO
- adr := adr + 4*stats.pc[i];
- WHILE m.PC + endPC < adr DO
- RTDT.SearchProc (m.PC + endPC, d1, d2, d3, startPC, endPC); INC (startPC, m.PC)
- END;
- IF adr > startPC THEN
- SYS.PUT (adr, RTDT.itw);
- startPC := MAX (LONGINT)
- END
- END;
- mod.mode := EntryMode
- ELSE
- Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
- Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
- END EntryModule;
- Syntax10.Scn.Fnt
- VAR stats: RTDC.Stat; i, adr: LONGINT; m: Modules.Module;
- BEGIN
- m := Modules.ThisMod (mod.name);
- IF m # mod.mod THEN mod.mode := NormalMode; mod.steps := NIL; mod.mod := m END;
- IF (mod.mode = StepOverMode) OR (mod.mode = EntryMode) THEN RestoreModule (mod) END;
- IF mod.mode = StepMode THEN RETURN END;
- IF mod.steps = NIL THEN GetBackupInstrs (mod) END;
- IF mod.steps # NIL THEN
- RTDC.Statements (mod.name, stats);
- adr := m.PC;
- FOR i := 0 TO LEN (stats.pc^)-1 DO
- adr := adr + 4*stats.pc[i];
- SYS.PUT (adr, RTDT.itw)
- END;
- mod.mode := StepMode
- ELSE
- Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
- Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
- END StepModule;
- Syntax10.Scn.Fnt
- VAR stats: RTDC.Stat; i, adr: LONGINT; m: Modules.Module;
- BEGIN
- m := Modules.ThisMod (mod.name);
- IF m # mod.mod THEN mod.mode := NormalMode; mod.steps := NIL; mod.mod := m END;
- IF mod.steps = NIL THEN GetBackupInstrs (mod) END;
- IF mod.steps # NIL THEN
- RTDC.Statements (mod.name, stats);
- adr := m.PC; beginPC := m.PC + beginPC; endPC := m.PC + endPC;
- FOR i := 0 TO LEN (stats.pc^)-1 DO
- adr := adr + 4*stats.pc[i];
- IF (beginPC < adr) & (adr < endPC) THEN SYS.PUT (adr, RTDT.itw) END
- END;
- mod.mode := StepOverMode
- ELSE
- Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
- Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
- END StepOver;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* set stepping in all modules *)
- VAR mod: ModuleInfo;
- BEGIN
- mod := modules;
- WHILE mod # NIL DO StepModule (mod); mod := mod.next END
- END StepAll;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* Remove all step info and all breakpoints from all modules *)
- VAR mod: ModuleInfo;
- BEGIN
- mod := modules;
- WHILE mod # NIL DO RestoreModule (mod); mod := mod.next END
- END RestoreAll;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* set breakpoints in all modules *)
- VAR m: GetBPMsg;
- BEGIN RestoreAll; Viewers.Broadcast (m)
- END BreakAll;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* set breakpoints at all entry-points of all modules *)
- VAR mod: ModuleInfo;
- BEGIN
- mod := modules;
- WHILE mod # NIL DO EntryModule (mod); mod := mod.next END
- END EntryAll;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* set step over for all procedures on stack *)
- VAR mod: ModuleInfo; p: RTDT.Proc;
- BEGIN
- RestoreAll;
- p := RTDT.procs;
- WHILE p # NIL DO
- mod := modules;
- WHILE (mod # NIL) & (mod.name # p.modName) DO mod := mod.next END;
- IF mod # NIL THEN StepOver (mod, p.beginPC, p.endPC) END;
- p := p.up
- END StepOverAll;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* release all debug info including list of debugged modules *)
- BEGIN RestoreAll; modules := NIL; RTDC.Release
- END CleanUp;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* add modules to list of debugged modules *)
- VAR mod: ModuleInfo;
- BEGIN
- WHILE s.class = Texts.Name DO
- mod := modules;
- WHILE (mod # NIL) & (mod.name # s.s) DO mod := mod.next END;
- IF mod = NIL THEN (* avoid debugging same module twice *)
- NEW (mod); COPY (s.s, mod.name);
- mod.next := modules; modules := mod
- END;
- Texts.Scan(s)
- END;
- (* EntryAll *)
- END AddModules;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* return modulename & textposition corresponding to pc *)
- VAR m: Modules.Module; stats: RTDC.Stat; i, curpc: LONGINT;
- BEGIN
- m := Modules.modules;
- WHILE (m # NIL) & ((pc < m.PC) OR (m.PC+4*m.codesize < pc)) DO m := m.link END;
- COPY (m.name, name); pc := (pc-m.PC) DIV 4;
- RTDC.Statements (name, stats); i := 0; curpc := stats.pc[0];
- WHILE (i < LEN (stats.pc^)-1) & (pc > curpc) DO INC (i); curpc := curpc+stats.pc[i] END;
- pos := stats.pos[i]
- END PCToPos;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- (* return pc relative to module 'name' corrsponding to textposition 'pos' *)
- VAR stats: RTDC.Stat; bestpos, curpc, i: LONGINT;
- BEGIN
- RTDC.Statements (name, stats);
- bestpos := stats.pos[0]; curpc := stats.pc[0]; pc := curpc;
- FOR i:=1 TO LEN (stats.pc^)-1 DO
- curpc := curpc + stats.pc[i];
- IF (stats.pos[i] <= pos) & (stats.pos[i] > bestpos) THEN
- bestpos := stats.pos[i]; pc := curpc
- END
- END;
- pc := 4*pc
- END PosToPC;
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- VAR mod: ModuleInfo; pc: LONGINT;
- BEGIN
- mod := modules;
- WHILE (mod # NIL) & (mod.name # name) DO mod := mod.next END;
- IF mod = NIL THEN RETURN FALSE END; (* Illegal breakpoint *)
- PosToPC (name, pos, pc);
- StepOver (mod, pc - 4, pc + 4);
- RETURN TRUE
- END BreakAtPC;
- MODULE RTDB; (* Run time debugger: Breakpoints & control flow; mah 25.10.94 (
- IMPORT RTDC, RTDT, Modules, SYS := SYSTEM, Texts, Oberon, Viewers, Display;
- CONST
- NormalMode = 0; (* debug modes for a module *)
- StepMode = 1;
- StepOverMode = 2;
- EntryMode = 3;
- ModuleInfo- = POINTER TO ModuleInfoDesc;
- ModuleInfoDesc- = RECORD
- GetBPMsg* = RECORD (Display.FrameMsg) END; (* sent to collect breakpoints *)
- modules-: ModuleInfo;
- w: Texts.Writer;
- PROCEDURE InstrAtPC (pc: LONGINT) : LONGINT;
- PROCEDURE GetBackupInstrs (mod: ModuleInfo);
- PROCEDURE RestoreModule (mod: ModuleInfo);
- PROCEDURE EntryModule (mod: ModuleInfo);
- PROCEDURE StepModule (mod: ModuleInfo);
- PROCEDURE StepOver (mod: ModuleInfo; beginPC, endPC: LONGINT);
- PROCEDURE StepAll*;
- PROCEDURE RestoreAll*;
- PROCEDURE BreakAll*;
- PROCEDURE EntryAll*;
- PROCEDURE StepOverAll*;
- PROCEDURE CleanUp*;
- PROCEDURE AddModules* (s: Texts.Scanner);
- PROCEDURE PCToPos* (pc: LONGINT; VAR name: ARRAY OF CHAR; VAR pos: LONGINT);
- PROCEDURE PosToPC* (VAR name: ARRAY OF CHAR; pos: LONGINT; VAR pc: LONGINT);
- PROCEDURE BreakAtPC* (VAR name: ARRAY OF CHAR; pos: LONGINT) : BOOLEAN;
- BEGIN Texts.OpenWriter (w); RTDT.LatestTrapInstr := InstrAtPC
- END RTDB.
-